// 以下为mysql库的测试代码
#include <iostream>
#include <string>
#include <cstring>         //strcasectr() 查找子串，不分大小写。
#include <cstdio>
#include <cstdlib>         //exit()
#include <mysql/mysql.h>   //引入mysql库

std::string host   = "127.0.0.1";
std::string user   = "test";
std::string passwd = "123456";
std::string db     = "test";
const int port = 3306;
int main()
{
    //测试：获取当前mysql客户端的版本
    std::cout << "mysql client version : " << mysql_get_client_info() << std::endl;

    //1. 创建并初始化mysql对象
    MYSQL *mysql = mysql_init(nullptr);
    if(mysql == nullptr)
    {
        std::cerr << "create mysql object fail!\n";
        exit(-1);
    }

    //3. 链接数据库(使用指定用户登录指定数据库，该用户必须有远程访问权限)
    //初始化完毕之后，必须先链接数据库，在进行后续操作。（mysql网络部分是基于TCP/IP的）
    if(mysql_real_connect(mysql, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
    {
        fprintf(stderr, "%s\n", mysql_error(mysql)); //显示连接时遇到的错误
        std::cerr << "Failed to connect to MySQL user!\n";
        exit(-2);
    }
    std::cout << "Successfully to connect to MySQL user!\n";

    //4. 设置链接的默认字符集为utf8，原始默认是latin1(拉丁文)
    mysql_set_character_set(mysql, "utf8");

    //5. 使用SQL对上面指定的数据库进行操作
    char sql[1024] = {0};
    while(1)
    {
        printf("mysql> ");
        fgets(sql, sizeof sql, stdin);
        if(strcasestr(sql, "quit"))
        {
            std::cout << "Bye" << std::endl;
            return 0;
        }
        int n = mysql_query(mysql, sql);
        std::cout << "result: " << n << std::endl;
        if(strcasestr(sql, "select") && 0 == n)
        {
            //6. 获取执行sql语句的结果
            //6.1 从myql对象里读取结果
            MYSQL_RES* res = mysql_store_result(mysql);
            if(res == nullptr) exit(-3);

            //6.2 从MYSQL_RES对象里获取行数
            int rows = mysql_num_rows(res);
            std::cout << "oj_questions表有" << rows << "行。\n";
            //6.3 从MYSQL_RES对象里获取列数
            int cols = mysql_num_fields(res);
            std::cout << "oj_questions表有" << cols << "列。\n";
            //6.4 从MYSQL_RES对象里获取列名
            MYSQL_FIELD *col_name = mysql_fetch_fields(res);//MYSQL_FIELD：结构体数组指针，指向结构体数组，结构体的name成员为字符串通过用来保存列名。
            for(int i = 0; i < cols; i++)
            {
                if(0 == i) std::cout << "|  ";
                std::cout << col_name[i].name << "  |  ";
                if(i == cols-1) std::cout << "\n";
            }
            //6.5 从MYSQL_RES对象里一行一行的读取结果
            MYSQL_ROW line; //创建MYSQL_ROW对象，用来保存表中内容
            for(int i = 0; i < rows; i++) //行数rows通过mysql_num_rows()获取。
            {
                line = mysql_fetch_row(res);
                
                for(int j = 0; j < cols; j++) //列数cols通过mysql_num_fields()获取。
                {
                    std::cout << line[j]<<" "; //打印第i行的第j列内容。
                }
                std::cout << std::endl;
            }

            std::cout << rows << " rows in set\n";
        }
        else
        {
            std::cout << "execl sql" << sql << "done" << std::endl;
        }
    }

    //2. 关闭mysql对象
    //mysql_close(mysql);
    return 0;
}

//编译时要加上：-L/lib64/mysql -lmysqlclient 帮助编译器找到头文件和库

